import type { PowerOutageController } from './definition'
import { getSetting } from '@/api/appliance'
import { POWER_STATES, POWER_STATE, OPERATION_POWER_OFF } from '@/constants/Command'
import { onceObserve } from '@/utils/mpHelper'
import { useRemote } from '@/controller/base/index'
import { trackEvent, TrackType } from '@/dataReport/tracks'
import { safeTrack } from '@/dataReport/dataReportUtil'

/**
 * 电源分4种类型：
 *  - 使用command断电，不支持远程开机
 *  - 使用setting断电，不支持远程开机
 *  - 使用setting待机，支持远程开机
 *  - 使用setting关机，支持远程开机
 *
 * * 断电类型：设备在线既开机，开机状态下 点击电源键时打开远程关机后需手动开机的确认弹框
 *
 *
 * 断电、待机、关机 判断逻辑：
 *  - 先判断 allSettings 内是否存在 BSH.Common.Setting.PowerState
 *     - 不存在时：使用【断电命令】，不可远程开机
 *     - 存在 PowerState 时，查询 Setting 详情：
 *        - 用 Setting 内的 constraints.allowedvalues 判断设备是否支持断电、待机、关机
 *           - 断电的 Setting 下发后，不支持远程开机
 *           - 待机、关机的 Setting 下发后，支持远程开机
 */
export const createPowerOutageState: () => PowerOutageController.PureState = () => ({
  // 是否使用断电命令
  usePowerOffCommand: false,
  // 关机的 Setting Value
  powerOffSettingValue: POWER_STATES.OFF,
})

export const PowerOutageGetters: PowerOutageController.Getters = {
  // 需要弹出确认关机提示框
  shouldConfirmShutdown() {
    return this.usePowerOffCommand || this.powerOffSettingValue === POWER_STATES.MAINS_OFF
  },
}

export const PowerOutageActions: PowerOutageController.FragmentActions = {
  async loadPowerSetting() {
    // 查找是否存在PowerState key 否则不查询
    const noPowerSetting = this._datasource.settings.every(({ key }) => key !== POWER_STATE)
    // 无PowerSetting 为使用断电命令的设备
    if (noPowerSetting) {
      this.powerState = this.isOffline ? POWER_STATES.MAINS_OFF : POWER_STATES.ON
      this.usePowerOffCommand = true
      return
    }

    // 查询PowerSetting
    const res = await getSetting(this._datasource.haId, POWER_STATE)
    const powerSetting = res.data

    // 设置为 Setting值对应的电源状态值
    this.powerState = res.data.value as POWER_STATES

    // 查询是否使用断电/待机
    if (!powerSetting?.constraints) return
    const { constraints } = powerSetting
    if (constraints.access !== 'readWrite' || !Array.isArray(constraints.allowedvalues)) return

    // 查找匹配的 PowerOff Setting值
    const powerOffValue = (constraints.allowedvalues as POWER_STATES[]).find((powerValue) => {
      return [POWER_STATES.MAINS_OFF, POWER_STATES.STANDBY, POWER_STATES.OFF].includes(powerValue)
    })
    if (powerOffValue) {
      this.powerOffSettingValue = powerOffValue
    }
  },
  async togglePowerState() {
    // 使用断电命令
    if (this.usePowerOffCommand) return this.shutdown()

    const powerStateValue = this.powerState !== POWER_STATES.ON ? POWER_STATES.ON : this.powerOffSettingValue

    const remote = useRemote(this)

    // 设置电源操作中状态
    if (this.powerState === POWER_STATES.ON) {
      this.isShuttingDown = true
    } else {
      this.isStartingUp = true
    }

    // 设置电源状态 (下发状态方法不能await，防止下发过程中电源状态变化，错过监听)
    remote.setSetting(POWER_STATE, powerStateValue, { ignoreError: true }).then((res) => {
      safeTrack(() => {
        trackEvent(
          'appliance_setting',
          {
            setting_key: POWER_STATE,
            setting_value: powerStateValue,
            successOrNot: res.code == 0,
            error_code: res.code,
            response_msg: res.msg,
          },
          TrackType.ApplianceDetail,
          'Appliance.Detail.Power.Control'
        )
      })
    })

    // 电源状态切换或断电时 都将关闭Loading
    await Promise.race([onceObserve(() => this.powerState), onceObserve(() => this.isOffline)])
    this.isShuttingDown = false
    this.isStartingUp = false
  },
  async shutdown() {
    const remote = useRemote(this)

    /**
     * 使用断电命令
     */
    if (this.usePowerOffCommand) {
      // 设置电源操作中状态
      this.isShuttingDown = true

      // 下发断电指令 (下发状态方法不能await，防止下发过程中电源状态变化，错过监听)
      remote.setCommand(OPERATION_POWER_OFF, true)

      // 离线状态时 关闭Loading
      await onceObserve(() => this.isOffline)
      this.isShuttingDown = false
    } else {
      /**
       * 使用电源Setting
       */
      // 设置电源操作中状态
      this.isShuttingDown = true

      // 下发关机设置 (下发状态方法不能await，防止下发过程中电源状态变化，错过监听)
      remote.setSetting(POWER_STATE, this.powerOffSettingValue, { ignoreError: true })

      // 电源状态切换或断电时 都将关闭Loading
      await Promise.race([onceObserve(() => this.powerState), onceObserve(() => this.isOffline)])
      this.isShuttingDown = false
    }
  },
}

export function usePowerOutageEffects<Control extends PowerOutageController.Control>(control: Control) {
  const { worker, remote } = control
  // 加载commands查询是否支持断电
  worker.onLoad(() => remote.loadSupportCommands())
  usePowerOutageBinding(control)
}

function usePowerOutageBinding<Control extends PowerOutageController.Control>(control: Control) {
  // 是否使用断电命令
  control.worker.useHasKeyBinding('usePowerOffCommand', {
    key: OPERATION_POWER_OFF,
    from: 'command',
  })
}
